package com.example.common.interceptor;

import com.example.common.entity.LoginUser;
import com.example.common.exception.BizException;
import com.example.common.exception.errcode.ErrCodeBase;
import com.example.common.utils.JwtUtils;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@Component
@Slf4j
@ConfigurationProperties("path-pattern")
public class GlobalInterceptor implements HandlerInterceptor {
    @Setter
    private List<String> excludeUrls;

    @Resource
    private ApplicationContext applicationContext;
    /**
     * 请求预处理
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //改变同源策略，允许任意源请求
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Max-Age", "86400");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        //######################### 校验token Start ########################################################
        String url = request.getServletPath();
        if (checkUrl(url)) {                                                //放行login等有关接口
            String token = request.getHeader("Authorization");
            if (token == null || token.trim().length() == 0) {
                throw new BizException(ErrCodeBase.TOKEN_NULL_EXCEPTION);   //token为null
            }
            JwtUtils.JwtUser jwtUser = JwtUtils.parseToken(token);          //登录用户注册成 Bean
            LoginUser loginUser = (LoginUser) applicationContext.getBean("loginUser");  //从容器中获取 LoginUser 的 Bean 对象
            loginUser.setUserId(Long.parseLong(jwtUser.getId()));
            loginUser.setUserName(jwtUser.getSubject());
        }
        //######################### 校验token End ########################################################

        String method = request.getMethod();            //请求方式
        String requestURI = request.getRequestURI();

        String remoteHost = request.getRemoteHost();    //登录的ip地址
        String remoteAddr = request.getRemoteAddr();    //登录的

        String userAgent = request.getHeader("User-Agent"); //访问的浏览器信息

        //todo 登录单独记录
        if ("POST".equals(method) && requestURI.contains("login")) {
            log.info("登录");
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        int status = response.getStatus();
        if (status != 200) {        //如果响应不为200
            //fixme 404 303 500 等状态
        }
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }

    /**
     * 校验url是否符合规则
     *
     * @param url
     * @return
     */
    private boolean checkUrl(String url) {
        AntPathMatcher matcher = new AntPathMatcher();
        for (String pattern : excludeUrls) {
            if (matcher.match(pattern, url)) {
                return false;
            }
        }
        return true;
    }
}